<?php

namespace app\kernel;

use think\App;
use think\console\Output;
use Workerman\Worker;

/**
 *  进程
 */
abstract class Process {

    /**
     * @var  App $app
     */
    protected $app;

    protected $worker;

    protected $option = [];

    protected $event  = [
        'onWorkerStart',
        'onConnect',
        'onMessage',
        'onClose',
        'onError',
        'onBufferFull',
        'onBufferDrain',
        'onWorkerReload',
        'onWebSocketConnect'
    ];

    protected $name;

    /**
     * @var Output
     */
    protected $out;

    /**
     * @var int  进程数量
     */
    protected $processNum = 1;

    public function __construct (App $app) {

        $this->app = $app;

        // 实例化 Websocket 服务
        $this->worker = new Worker();
        $this->worker->count = $this->processNum;
        $this->worker->name = empty($this->name) ? get_class() : $this->name;
        // 设置参数
        if (!empty($this->option)) {
            foreach ($this->option as $key => $val) {
                $this->worker->$key = $val;
            }
        }
        // 设置回调
        foreach ($this->event as $event) {
            if (method_exists($this, $event)) {
                $this->worker->$event = [
                    $this,
                    $event
                ];
            }
        }
        $this->beforeWorkerStart($this);
        $this->out = $this->app->make(Output::class);
    }

    /**
     * 开始前的事件
     * @param Process $process
     * @return mixed
     */
    protected function beforeWorkerStart (Process $process) {

    }

    /**
     * 启动
     * @return void
     */
    public function onWorkerStart () {

        $this->workerStart($this);
    }

    /**
     * 开启进程
     * @param Process $process
     * @return mixed
     */
    abstract protected function workerStart (Process $process);

    /**
     * 设置进程数量
     * @return void
     */
    public function setWorkerNum ($num) {

        $this->processNum = $num;
        if (!empty($this->worker)) {
            $this->worker->count = $this->processNum;
        }
    }

    public function setWorkerName ($name) {

        $this->worker->name = $name;
    }

}